#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   APP_RoutineControl_0x31_test.py
@Time    :   2025/04/08 13:31:28
@Author  :   YangLiang 
@Version :   1.0
@Contact :   yangl@genvict.com
@License :   (C)Copyright 2022-2025
@Desc    :   UDS 31服务测试脚本
'''

from pytest_assume.plugin import assume
import pytest
import logging
import time
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable
from sqlalchemy import false
sys.dont_write_bytecode = True

# 正响应测试用例
routineControl_positive = [
    ("31 01 02 03", "71 01 02 03"),           # 扩展会话 - 启动例程
]

# NRC测试用例
routineControl_NRC13 = [
    ("31", "7F 31 13"),                         # 缺失子功能
    ("31 01", "7F 31 13"),                      # 缺失DID
    ("31 01 02", "7F 31 13"),                   # 不完整DID
    ("31 01 02 03 04", "7F 31 13"),             # 过多参数
    ("31 04", "7F 31 13"),                      # 无效子功能
    ("31 01 02 03 04 05 06", "7F 31 13"),       # 过多参数    
]

routineControl_NRC12 = [
    ("31 00 02 03", "7F 31 12"),               # 无效子功能0x00
    ("31 02 02 03", "7F 31 12"),               # 未定义子功能0x02
    ("31 03 02 03", "7F 31 12"),               # 未定义子功能0x03
    ("31 05 02 03", "7F 31 12"),               # 未定义子功能0x05
    ("31 FF 02 03", "7F 31 12"),               # 保留子功能0xFF
]

routineControl_NRC31 = [
    ("31 01 01 02", "7F 31 31"),               # 不支持DID 0102
    ("31 02 03 04", "7F 31 31"),               # 不支持DID 0304
    ("31 03 05 06", "7F 31 31"),               # 不支持DID 0506
    ("31 01 FF 01", "7F 31 31"),               # 03不支持DID FF01
    ("31 01 DD 02", "7F 31 31"),               # 03不支持DID DD02
    ("31 01 DD 03", "7F 31 31"),               # 03不支持DID DD03
    ("31 01 DD 04", "7F 31 31"),               # 03不支持DID DD04
    ("31 01 DD 0F", "7F 31 31"),               # 03不支持DID DD0F
    ("31 03 DD 04", "7F 31 31"),               # 03不支持DID DD04
    ("31 01 DD 41", "7F 31 31"),               # 03不支持DID DD41
    ("31 01 DD 42", "7F 31 31"),               # 03不支持DID DD42
    ("31 01 DD 43", "7F 31 31"),               # 03不支持DID DD43
    ("31 01 DD 44", "7F 31 31"),               # 03不支持DID DD44
]

routineControl_NRC33 = [          
    ("31 01 02 03", "7F 31 33"),               
]

routineControl_NRC22 = [
    ("31 01 02 03", "7F 31 22"),               # 条件不满足
]

routineControl_NRC24 = [
    ("31 03 DD 04", "7F 31 24"),               # 请求序列错误
]

routineControl_NRC72 = [
    ("31 01 FF 00", "7F 31 72"),               # 一般扩展禁止
    ("31 02 FF 01", "7F 31 72"),               # 一般扩展禁止
    ("31 03 DD 02", "7F 31 72")                # 一般扩展禁止
]

routineControl_NRC7F = [
    ("31 01 02 03", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 01 DD 04", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 03 DD 04", "7F 31 7F"),           # 扩展会话 - 查询状态
    ("31 01 DD 40", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 01 DD 41", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 01 DD 42", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 01 DD 43", "7F 31 7F"),           # 扩展会话 - 启动例程
    ("31 01 DD 44", "7F 31 7F"),           # 扩展会话 - 启动例程
]

routineControl_Noresponse = [
    ("31 01 02 03", ""),           # 功能寻址无响应
    ("31 03 02 03", ""),           # 功能寻址无响应
    ("31 01 02 03 01", ""),        # 功能寻址无响应
    ("31 01 02 05", ""),           # 功能寻址无响应
    ("31 01 FF 00", ""),           
    ("31 02 FF 01", ""),           
    ("31 03 DD 02", "")           
]

class Test_APP_RoutineControl_Phy(object):
    '''物理寻址测试用例'''
    ids = [f"Request {req}" for req, resp in routineControl_positive]
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-正响应测试')
    @allure.description('验证物理寻址扩展会话下31服务的正响应')
    @pytest.mark.parametrize('req,resp', routineControl_positive, ids=ids)
    def test_routineControl_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        # 测试支持的DID
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)


    '''NRC测试'''
    ids = [f"Request {req}" for req, resp in routineControl_NRC13]
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC13测试')
    @allure.description('验证物理寻址扩展会话下31服务NRC13响应')
    @pytest.mark.parametrize('req,resp', routineControl_NRC13, ids=ids)
    def test_routineControl_NRC13_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    ids = [f"Request {req}" for req, resp in routineControl_NRC12]
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC12测试')
    @allure.description('验证物理寻址扩展会话下31服务NRC12响应')
    @pytest.mark.parametrize('req,resp', routineControl_NRC12, ids=ids)
    def test_routineControl_NRC12_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    ids = [f"Request {req}" for req, resp in routineControl_NRC31]
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC31测试')
    @allure.description('验证物理寻址扩展会话下31服务NRC31响应')
    @pytest.mark.parametrize('req,resp', routineControl_NRC31, ids=ids)
    def test_routineControl_NRC31_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    # ids = [f"Request {req}" for req, resp in routineControl_NRC33]
    # @allure.severity('normal')
    # @allure.title('物理寻址-扩展会话-NRC33测试')
    # @allure.description('验证物理寻址扩展会话下31服务NRC33响应')
    # @pytest.mark.parametrize('req,resp', routineControl_NRC33, ids=ids)
    # def test_routineControl_NRC33_Extended_Phy(self, action, Driver, req, resp):
    #     iStep = 1
    #     iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    ids = [f"Request {req}" for req, resp in routineControl_NRC22]
    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC22测试')
    @allure.description('验证物理寻址扩展会话下31服务NRC22响应')
    @pytest.mark.parametrize('req,resp', routineControl_NRC22, ids=ids)
    def test_routineControl_NRC22_Extended_Phy(self, action, Driver, req, resp):
        iStep = 1
        # 设置车速>3kph
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 8)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)
        # 重置车速
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 0)

    # ids = [f"Request {req}" for req, resp in routineControl_NRC24]
    # @allure.severity('normal')
    # @allure.title('物理寻址-扩展会话-NRC24测试')
    # @allure.description('验证物理寻址扩展会话下31服务NRC24响应')
    # @pytest.mark.parametrize('req,resp', routineControl_NRC24, ids=ids)
    # def test_routineControl_NRC24_Extended_Phy(self, action, Driver, req, resp):
    #     iStep = 1
    #     iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    # ids = [f"Request {req}" for req, resp in routineControl_NRC72]
    # @allure.severity('normal')
    # @allure.title('物理寻址-扩展会话-NRC72测试')
    # @allure.description('验证物理寻址扩展会话下31服务NRC72响应')
    # @pytest.mark.parametrize('req,resp', routineControl_NRC72, ids=ids)
    # def test_routineControl_NRC72_Extended_Phy(self, action, Driver, req, resp):
    #     iStep = 1
    #     iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 3, iStep, False)

    ids = [f"Request {req}" for req, resp in routineControl_NRC7F]
    @allure.severity('normal')
    @allure.title('物理寻址-默认会话-NRC7F测试')
    @allure.description('验证物理寻址默认会话下31服务NRC7F响应')
    @pytest.mark.parametrize('req,resp', routineControl_NRC7F, ids=ids)
    def test_routineControl_NRC7F_Default_Phy(self, action, Driver, req, resp):
        iStep = 1
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 1, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC13 NRC12优先级')
    @allure.description('验证物理寻址扩展会话下31服务NRC13 NRC12优先级')
    def test_routineControl_NRC13andNRC12_Priority_Extended_Phy(self, action, Driver):
        iStep = 1
        # 测试NRC13 12优先级
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 05 02", "7F 31 13", 3, iStep, False)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 05", "7F 31 13", 0, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC12 NRC13优先级')
    @allure.description('验证物理寻址扩展会话下31服务NRC12 NRC13优先级')
    def test_routineControl_NRC12andNRC13_Priority_Extended_Phy(self, action, Driver):
        iStep = 1
        # 测试NRC12 13优先级
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 05 02 03 01 01", "7F 31 12", 3, iStep, False)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC13 NRC22优先级')
    @allure.description('验证物理寻址扩展会话下31服务NRC13 NRC22优先级')
    def test_routineControl_NRC13andNRC22_Priority_Extended_Phy(self, action, Driver):
        iStep = 1
        # 测试NRC13 22优先级
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 8)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 05 FF", "7F 31 13", 3, iStep, False)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 01 02 03 01 02", "7F 31 13", 0, iStep, False)
        # 重置车速
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 0)

    @allure.severity('normal')
    @allure.title('物理寻址-扩展会话-NRC12 NRC22优先级')
    @allure.description('验证物理寻址扩展会话下31服务NRC12 NRC22优先级')
    def test_routineControl_NRC12andNRC22_Priority_Extended_Phy(self, action, Driver):
        iStep = 1
        # 测试NRC12 22优先级
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 8)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 05 02 03", "7F 31 12", 3, iStep, False)
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "31 06 02 03", "7F 31 12", 0, iStep, False)
        # 重置车速
        iStep = Driver['CAN'].SetVehicleSpeed(Driver, iStep, 0)

class Test_APP_RoutineControl_Func(object):
    '''功能寻址测试用例'''
    '''功能寻址测试用例'''
    ids = [f"Request {req}" for req, resp in routineControl_Noresponse]
    @allure.severity('normal')
    @allure.title('功能寻址-扩展会话-正响应测试')
    @allure.description('验证功能寻址扩展会话下31服务的正响应')
    @pytest.mark.parametrize('req,resp', routineControl_Noresponse, ids=ids)
    def test_routineControl_Default_Func(self, action, Driver, req, resp):
        iStep = 1
        # 测试支持的DID
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, '', 1, iStep, False, 'UDSFun')

    ids = [f"Request {req}" for req, resp in routineControl_Noresponse]
    @allure.severity('normal')
    @allure.title('功能寻址-扩展会话-正响应测试')
    @allure.description('验证功能寻址扩展会话下31服务的正响应')
    @pytest.mark.parametrize('req,resp', routineControl_Noresponse, ids=ids)
    def test_routineControl_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        # 测试支持的DID
        iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, '', 3, iStep, False, 'UDSFun')